package ch.bfh.mobicomp.soda2.magnetometer;

import ch.bfh.mobicomp.soda2.magnetometer.interfaces.IFileNameKnowing;
import ch.bfh.mobicomp.soda2.magnetometer.utils.FileWriting;
import ch.bfh.mobicomp.soda2.magnetometer.utils.SharedPreferencesManager;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;

public class MagnetoListener implements SensorEventListener, IFileNameKnowing {
	
	private SensorManager mSensorManager;
	private Sensor mSensor;
	public static final float MOVEMENT_THRESHOLD = (float) 3;
	public static final short MEASURES_MAX_SIZE_FOR_NOTMOVING = 20;
	private float[] lastReferenceMeasure = {0,0,0};
	private int measureCounter;
	private boolean isMoving = true;
	
	private SharedPreferencesManager storage;
	private FileWriting filewriter;


	public MagnetoListener(Context context) {
		
		storage = new SharedPreferencesManager(context);
		filewriter = new FileWriting(this);
		mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
		mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
		Log.d(MainActivity.LOG_TAG, "Res: " + String.valueOf(mSensor.getResolution()));
		Log.d(MainActivity.LOG_TAG, "MeasureService onCreate");

		this.isMoving = storage.getBoolean(SharedPreferencesManager.KEY_IS_MOVING);
		Log.d(MainActivity.LOG_TAG, "lastState:" + String.valueOf(this.isMoving));
		onStartListening();
	}

	public void onStopListening() {
		mSensorManager.unregisterListener(this);
	}
	
	public void onStartListening() {
		mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		filewriter.fileLog(System.currentTimeMillis() + ">" 
				+ String.valueOf(event.values[0]) + " " 
				+ String.valueOf(event.values[1]) + " " 
				+ String.valueOf(event.values[2]) + "\n"
		); 
		
//		Log.d(MainActivity.LOG_TAG, String.valueOf(event.values[0]));
		
		if	(	(	calculateMinimalDifferenceBetween(lastReferenceMeasure[0],event.values[0]) + 
					calculateMinimalDifferenceBetween(lastReferenceMeasure[1], event.values[1]) + 
					calculateMinimalDifferenceBetween(lastReferenceMeasure[2], event.values[2])
				) 		> MagnetoListener.MOVEMENT_THRESHOLD
			) {
			
			measureCounter = 0;
//			Log.d(MainActivity.LOG_TAG, "measureCounter = 0");
			
			if(this.isMoving) {
				lastReferenceMeasure[0] = event.values[0];
				lastReferenceMeasure[1] = event.values[1];
				lastReferenceMeasure[2] = event.values[2];
			}
			else {
				this.isMoving = true;
				this.storage.putBoolean(SharedPreferencesManager.KEY_IS_MOVING, true);
				Log.d(MainActivity.LOG_TAG, "isMoving");
			}
		}
		else {
			
			if(this.isMoving) {
				
				measureCounter++;
				
				if(measureCounter >= MagnetoListener.MEASURES_MAX_SIZE_FOR_NOTMOVING){
					this.isMoving = false;
					this.storage.putBoolean(SharedPreferencesManager.KEY_IS_MOVING, false);
					Log.d(MainActivity.LOG_TAG, "notMoving");
					measureCounter = 0;
				}
			}
		}
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {}

	@Override
	public void onFileNameChanged(String name) {
		this.storage.putString(SharedPreferencesManager.KEY_FILE_NAME, name);	
	}
	
	private float calculateMinimalDifferenceBetween(float a, float b) {
		return Math.min(Math.min(Math.abs(a-b), Math.abs(a-b-360)), Math.abs(a-b+360));
	}
}